#include "my_hash.h"


uint8_t h_init(node* tab){
	
	uint8_t i = 	0;
	uint8_t ok = 	1;
	
	for(; i< ROOT_INDEX -1; i++)
		ok = h_insert(tab, ROOT_INDEX, i, i);	

	ok = h_insert(tab,ROOT_INDEX,255,255);	
	return ok;
}

hindex_t inline h_get_index(value_t dad,uint8_t symbol){	
	
	hindex_t key = (52347*symbol + 155721*dad )%M1_ENTRY;	
	
	return key;
}

hindex_t h_get(node* tab,value_t dad,uint8_t symbol){

	hindex_t i = h_get_index(dad,symbol);
	while(1){
		if (tab[i].symbol ==0 && tab[i].dad != ROOT_INDEX)
			break;
	
		if (tab[i].symbol == symbol && tab[i].dad == dad)
			return tab[i].value;
		i = (i+ 1) %M1_ENTRY;
	}
	return -1;
}

uint8_t h_insert(node* tab,value_t dad,uint8_t symbol,value_t value){

	hindex_t i =	h_get_index(dad,symbol);
	
	while(tab[i].value != 0 || tab[i].dad == ROOT_INDEX)	
		i = (i +1) % M1_ENTRY;
	
	tab[i].dad = 	dad;
	tab[i].symbol =	symbol;
	tab[i].value =	value;	

	return 1;	
}

uint8_t h_flush(node* tab){

	memset(tab, 0, M1_ENTRY*sizeof(node)); 
	h_init(tab);
	
	return 1;
}

void h_print(node* tab){

	int i= 0;
	int n = 0;
	printf("Hash :\tDad\tSymbol\tvalue\n");
	for(i = 0 ; i < M1_ENTRY; i++){	
		if(tab[i].value !=0 || tab[i].dad == ROOT_INDEX){
			printf("%u :\t%u\t%c\t%u\n",i,tab[i].dad,tab[i].symbol,tab[i].value);
			n++;
		}
	}
	printf("VALORE N :\t%u\n",n);
}

void h_print2(node* tab,hindex_t padre,uint8_t depth){

	int i= 0;
	int j= depth*2;
	if (padre !=0){
		for(i = 0 ; i < M1_ENTRY; i++){
			if(tab[i].dad == padre && tab[i].symbol>=0 && tab[i].symbol<256 ){
				j= depth*2;
				while ( j >0 ){
					printf("\t");
					j--;
				}
				if(depth == 0)
					printf("%d",tab[i].dad);
				printf("\t-%c-> %u\n",tab[i].symbol,tab[i].value);
				if(tab[i].value != 0);{
					h_print2(tab,tab[i].value,(depth+1));

				}
			}
		}
	}
}


